/*->c.vxterm */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"
#include "h.bbc"
#include "h.flex"


#include "h.wos"
#include "h.main"
#include "h.ram"
#include "h.mym"
#include "h.def"


#include "h.term"

#include "h.replay"

#include "h.vtdef"
#include "h.vtwimp"
#include "h.vtfile"
#include "h.vtscr"

#include "h.vxdef"
#include "h.vxwimp"
#include "h.vxcol"
#include "h.vxsend"
#include "h.mxterm"


#include "h.vxterm"


/***************************************************************************/
/*
 Code for Viewdata Terminal
*/
/*****************************************************************************/
                       /* conceal and reveal */

void conrec(vxscreen * vsc,int search,int replace)
{
 int    x;
 int    y;
 int  * p;
 int    modded;

 for(y=0;y<24;y++)
 {
  p=vsc->tcbuf[y];
  modded=0;

  for(x=0;x<40;x++,p++)
  {
   if(*p==search) 
   {
    *p=replace;
    modded=1;
   }
  }
  if(modded) convertline(vsc,y);
 }

 if(vxpendredraw)     /* notice we don't know the window handle */
 {
  vxdoredraw(vsc);
  vxpendredraw=0;
 }
}




/* scan matrix for cnc dummys. write cnc's. dummy cnc=142 */

void conceal(void)
{ 
 conrec(vscr,142,152);
}




/* scan matrix for cnc's replace with cnc dummys */

void reveal(void)
{
 conrec(vscr,152,142);
}




/*****************************************************************************/



void vxmarkredraw(vxscreen * vsc,int y,int xlo,int xhi)
{
 if(vsc->rlo[y]==vsc->rhi[y])
 {
  vsc->rlo[y]=xlo;
  vsc->rhi[y]=xhi+1;
 }
 else
 {
  if(xlo<vsc->rlo[y]) vsc->rlo[y]=xlo;
  if(xhi>=vsc->rhi[y]) vsc->rhi[y]=xhi+1;
 }

 vxpendredraw=1;
}





void vxsetcursor(void)
{
 if(!vxmovecurs && vxcurs && vxcursphase)
 {
  vxmarkredraw(vscr,ttvy,ttvx,ttvx);
  vxmovecurs=1;
 }
}







void viewclslo(vxscreen * vsc)
{
 int y;
 int x;

 int front=vxphysicalcolour(WHITE);
 int back=vxphysicalcolour(BLACK);
 int colours;

 front=front ^ back;

 colours=(front<<24)+(back<<16);


 for(y=0;y<vsc->height;y++)
 {
  vsc->rlo[y]=vsc->rhi[y]=0;
  vsc->flo[y]=vsc->fhi[y]=0;
  vsc->attr[y]=VXASH;

  for(x=0;x<40;x++)
  {
   vsc->tvbuf[y][x]=colours;
   vsc->tcbuf[y][x]=SPC;
  }
 }

 ttvx=ttvy=0;
}



void viewcls(void)
{
 int y;

 if(replayfix)
 {
  replayclscode=VXCLS;
  return;
 }

 viewclslo(vscr);
 for(y=0;y<vscr->height;y++)
 {
  vscr->rhi[y]=40;
  vxpendredraw=1;
 }
}



int vxfindcolours(int foreground,int background,int style)
{
 foreground=vxphysicalcolour(foreground);
 background=vxphysicalcolour(background);
 foreground=foreground ^ background;
 return((style & 0xFFFF)+(foreground<<24)+(background<<16));
}



/* takes line y and maps cbuf into vbuf */

void convertline(vxscreen * vscr,int y) 
{ 
 int hold;
 int holdchar;
 int graphics;
 int seperated;
 int concealed;
 int foreground;
 int background;
 int x;
 int byte;
 int code;
 int oheight;
 int dheight;
 int style;
 int curxl;
 int curxh;
 int  * vpoint;
 int  * cpoint;
 int grid;

 oheight=vscr->attr[y];
 if(oheight==2) return;
 dheight=0;

 hold=0;
 holdchar=0;
 graphics=0;
 seperated=0;
 concealed=0;
 foreground=WHITE;
 background=BLACK;

 style=vxfindcolours(foreground,background,0);

 vpoint=&(vscr->tvbuf[y][0]);
 cpoint=&(vscr->tcbuf[y][0]);
 curxl=0;
 curxh=39;
         
 grid=vscr->pixelgrid;

 vscr->flo[y]=vscr->fhi[y]=0;

 for(x=0;x<40;x++)
 {
  code=byte=*cpoint;
  if(code>128)
  {
   if(code<136) graphics=0;

   if(code==156)
   {  /* black */
    background=BLACK;
    style=vxfindcolours(foreground,background,style);
   }
   else
   if(code==157)
   {  /* new   */
    background=foreground;
    style=vxfindcolours(foreground,background,style);
   }
   else if(code==158) hold=1;
   else if(code==153) seperated=0;
   else if(code==154) seperated=VXUNDER;

   if(graphics && hold) byte=holdchar;
   else                 byte=32;

   if(code>144 && code<152) graphics=1;

   if(grid && graphics) seperated=VXUNDER;
  }


  /* now print character */

  if(concealed) byte=0;
  else
  if(graphics)
  {
   holdchar=byte;
   if(byte<64 && byte>32)  byte+=352-32+seperated;
   else
   if(byte>95 && byte<127) byte+=416-96+seperated;
   else
   if(byte==127) byte=415+seperated;
   else                                /* assuming no one extend the cset */
   if(grid && byte==32 && code<128) byte=506+VXUNDER;
   else
                 byte-=32;
  }
  else           byte-=32;


  if(*vpoint==(byte+style))
  {
   if(curxh==39) curxl=x;
  }
  else curxh=x;

  *vpoint=byte+style;

  if((*vpoint) & (VXFLASH1+VXFLASH2))
  {
   if(vscr->flo[y]==vscr->fhi[y])
   {
    vscr->flo[y]=x;
    vscr->fhi[y]=x+1;
   }
   else
   if(x>=vscr->fhi[y])
   {
    vscr->fhi[y]=x+1;
   }
  }

  if(code>128)
  {
   if(code<136)
   {
    graphics=0;
    concealed=0;
    foreground=code-128;
    style=vxfindcolours(foreground,background,style);
   }
   else
   if(code>144 && code<152)
   {
    graphics=1;
    concealed=0;
    foreground=code-144;
    style=vxfindcolours(foreground,background,style);
   }
   else
   switch(code)
   {
    case  136: /* flash */
              style=style | 0x1000;
              break;
 
    case  137: /* steady */
              style=style & 0xFFFFEF00;
              break;

    case  141: /* dheight */
              if(y==23) break;
              style=style | 0x400;
              dheight=1;
              break;

     case  140: /* single */
               style=style & 0xFFFFFB00;
               break;

     case  159:
               hold=0;
               break;

     case  152:
               concealed=1;
               break;
   }
  }
  cpoint++;
  vpoint++;
 }



 if(dheight && oheight==0)
 {
  /* convert this line and the one below to dheight pair */
  /* notice that if the one below is the top of a pair then 
     have to fix that as well */

  if(y<22 && vscr->attr[y+1])
  {
   vpoint=&(vscr->tvbuf[y+2][0]);
   cpoint=&(vscr->tcbuf[y+2][0]);
   for(x=0;x<40;x++)
   {
    if((*cpoint)==141) *cpoint=140;
    *vpoint=(*vpoint) & 0xFFFFF3FF;
    cpoint++;
    vpoint++;
   }
   vxmarkredraw(vscr,y+2,0,39);
   vscr->attr[y+2]=0;
  }

  vpoint=&(vscr->tvbuf[y][0]);
  cpoint=&(vscr->tcbuf[y][0]);

  for(x=0;x<=curxh;x++)
  {
   if(*vpoint & 0x400) 
   {
    *(vpoint+40)=(*vpoint)^0xC00;
    *(cpoint+40)=*cpoint;
   }
   else 
   {
    *(vpoint+40)=(((*vpoint) & 0xFFFFFE00)/* +32 */) ^ 0xC00;
    *(cpoint+40)=SPC;
   }
   cpoint++;
   vpoint++;
  }

  vscr->flo[y+1]=vscr->flo[y];  /* copy flash data */
  vscr->fhi[y+1]=vscr->fhi[y];

  vscr->attr[y]=1;
  vxmarkredraw(vscr,y,0,curxh);
  vscr->attr[y+1]=2;
  vxmarkredraw(vscr,y+1,0,curxh);
 }
 else
 if(dheight && oheight)
 { /* no change */

  vpoint=&(vscr->tvbuf[y][curxl]);
  cpoint=&(vscr->tcbuf[y][curxl]);

  for(x=curxl;x<=curxh;x++)
  {
   if(*vpoint & 0x400) 
   {
    *(vpoint+40)=(*vpoint)^0xC00;
    *(cpoint+40)=*cpoint;
   }
   else 
   {
    *(vpoint+40)=(((*vpoint) & 0xFFFFFE00)/* +32 */) ^ 0xC00;
    *(cpoint+40)=SPC;
   }
   cpoint++;
   vpoint++;
  }
  vscr->flo[y+1]=vscr->flo[y];  /* copy flash data */
  vscr->fhi[y+1]=vscr->fhi[y];

  vxmarkredraw(vscr,y,curxl,curxh);
  vxmarkredraw(vscr,y+1,curxl,curxh);
 }
 else
 if(!dheight && oheight)
 { /* changing dheight to single */

  vpoint=&(vscr->tvbuf[y+1][0]);
  cpoint=&(vscr->tcbuf[y+1][0]);

  for(x=0;x<40;x++)
  {
   if((*cpoint)==141) *cpoint=140;
   *vpoint=(*vpoint) & 0xFFFFF3FF;
   cpoint++;
   vpoint++;
  }

  vscr->flo[y+1]=vscr->flo[y];  /* copy flash data */
  vscr->fhi[y+1]=vscr->fhi[y];

  vxmarkredraw(vscr,y,0,curxh);
  vxmarkredraw(vscr,y+1,0,curxh);
  vscr->attr[y+1]=vscr->attr[y]=0;
 }
 else 
 { /* single to single */
  vxmarkredraw(vscr,y,curxl,curxh);
 }

 vxmodded=0;
}


void viewdown(void)
{
 vxsetcursor();
 if(vxmodded) convertline(vscr,ttvy);
 if(++ttvy==24) ttvy=0;
}


void viewcrlf(void)
{
 vxsetcursor();
 if(vxmodded) convertline(vscr,ttvy);
 if(++ttvy==24) ttvy=0;
 ttvx=0;
}


void viewup(void)
{
 vxsetcursor();
 if(vxmodded) convertline(vscr,ttvy);
 if(--ttvy==-1) ttvy=23;
}


void viewright(void)
{
 vxsetcursor();
 if(++ttvx==40)
 {
  ttvx=0;
  viewdown();
 }
}


void viewleft(void)
{
 vxsetcursor();
 if(--ttvx==-1)
 {
  ttvx=39;
  viewup();
 }
}


void viewhome(void)
{
 if(vxmodded) convertline(vscr,ttvy);
 vxsetcursor();
 ttvx=ttvy=0;
}



int vxmaskbyte(int byte)
{
 if(!vxbit8c) byte=byte & 0x7F;
 return(byte);
}


void viewx(int byte)
{
 if(!vxbit8c) byte=byte & 0x7F;

 if(minitel)
 {
  minitelx(byte);
  return;
 }

 if(vxhash)
 {
  vxhash=0;
  if(byte=='7' && ttns) 
  {
   vtsetfocusfront();
   vtcls();
   return;
  }
  else
  if(byte=='9')
  {
   setterm(TERMMX);
   return;
  }
  else
  if(byte=='0') byte=12;
 }

 if(viewescflag)
 {
  viewescflag=vxhash=0;

  if(ttns)
  {
   if(byte=='a') 
   {
    vtsetfocusfront();
    vtcls();
    return;
   }
   else
   if(byte=='c') byte=12;
  }

  if(byte=='#')
  {
   vxhash=1;
   return;
  }


  if(byte!=12)
  {
   if(byte<128) byte+=64;
   if(byte>159 || byte<128)
   {
    viewright();
    return;
   }
  }
 }


 if(byte<32)
 {
  switch(byte)
  {
   case ENQ:
            vxanswerback();
            break;

   case BEL:
            if(vxbeep) beep();
            break;

   case   8:
            viewleft();
            break;

   case   9:
            viewright();
            break;

   case  10:
            viewdown();
            break;

   case  11:
            viewup();
            break;

   case  12:
            viewcls();
            break;

   case CR:
           if(!spconcode && spoolflag)
           {
            myspool(CR);
            if(vxrxcrlnf) myspool(LF);
           }
           
           if(vxrxcrlnf)
           {
            viewcrlf();
           }
           else
           {
            vxsetcursor();
            ttvx=0;
           }
           break;

   case  17:
            vxcurs=vxcursphase=1;
            vxsetcursor();
            break;

   case  20:
            vxsetcursor();
            vxcurs=0;
            break;

   case  27:
            viewescflag=1;
            break;

   case  30:
            viewhome();
            break;
  }
  return;
 }

 if(vscr->attr[ttvy]==2)
 {
  viewright();
  return;
 }

 vscr->tcbuf[ttvy][ttvx]=byte;
 vxmodded=1;
 viewright();

 if(!spconcode && spoolflag)
 {
  if(byte<127) myspool(byte);
  else         myspool(SPC);
 }
}



void vxreset(void)
{
 viewescflag=vxhash=0;
 vxcurs=1;
 mxreset();
 viewcls();
}


